JAVA非阻塞同步算法与CAS无锁算法

JDK1.5之前靠synchronized关键字保持同步,采用独占方式访问变量
乐观锁与悲观锁
独占锁是悲观锁,然而synchronized是独占锁(悲观的),它会导致其他需要锁的线程挂起,等待那个线程释放锁
乐观锁,每次不加锁而是假设没有冲突而去完成某项操作,冲突失败则重试,直至成功。

volatile
1.它保证变量修改,对于任何线程是可见的,
2.它保证 指令顺序不会重新排序,保证正确顺序下去,
当volatile修饰的变量修改时,它会将其他线程的这个变量变成无效状态,使得其他线程不得不向主存中访问变量。

java中的原子操作
原子操作:在一步之内就完成而且不能被中断。原子操作在多线程环境是安全的
对于long,double类型,并不是原子类型的操作。 对于64位操作系统,要分两步,一步写32位,一步写32位。
volatile本身不保证获取和设置操作是原子性,只保证修改的可见性。然而,java内存模型保证声明volatile的long和double变量的get和set操作是原子的。
例如: private volatile long foo;

AtomicInteger 内部成员private volatile int value;
synchronized是悲观的,先获取锁,再更新
原子变量更新是乐观的

CAS无锁算法
CAS , 是CPU指令,它是一种乐观锁技术,多个线程尝试更新同一个变量,其中一个线程更新这一个变量,其他线程操作实拍,失败线程不会挂起,而是被通知竞争失败,再次尝试。
CAS有3个操作数,内存值V,旧的预期值A,新的值B 如果 V==B那么更新值变为

//CAS比较与交换代码
do{
    备份旧值
    基于旧值构造新值(用一个新的变量存储新值) 
}while(!CAS(内存值,旧值,新值))

public final long getAndAdd(long delta) {
         while (true) {
             long current = get();
             long next = current + delta;
             if (compareAndSet(current, next))
                 return current;
         }
     }
     //

V与A比较如果V没有被修改,那么替换新值,如果被修改了内存中的值返回false,并放弃刚才的操作,然后重新再次执行,直到执行成功
对CAS的支持 AtomicInt,AtomicLong.incrementAndGet()

自旋锁
自旋锁是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线程改变时 才能进入临界区。

public class SpinLock {

  private AtomicReference<Thread> sign =new AtomicReference<>();

  public void lock(){
    Thread current = Thread.currentThread();
    while(!sign .compareAndSet(null, current)){
    }
  }

  public void unlock (){
    Thread current = Thread.currentThread();
    sign .compareAndSet(current, null);
  }
}

使用了CAS原子操作,lock函数将owner设置为当前线程,并且预测原来的值为空。unlock函数将owner设置为null,并且预测值为当前线程。
当有第二个线程调用lock操作时由于owner值不为空,导致循环一直被执行,直至第一个线程调用unlock函数将owner设置为null,第二个线程才能进入临界区。
由于自旋锁只是将当前线程不停地执行循环体,不进行线程状态的改变,所以响应速度更快。但当线程数不停增加时,性能下降明显,因为每个线程都需要执行,占用CPU时间。如果线程竞争不激烈,并且保持锁的时间段。适合使用自旋锁。

CAS例子:非阻塞栈

do{
    oldHead = head.get();
    newHead.next = oldHead;
}while(!head.compareAndSet(oldHead,newHead));

首先从头中取出头元素,然后将新的头的next指向旧的元素(此时头是newHead),那么开始进行CAS算法,从内存中取出栈的头部和旧的头部进行比较,如果相同,进行更新,如果取出的栈头部与oldHead不同,那么撤销操作,循环不断的检测。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值